/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.admin.base;

import vip.dexian.common.Message;
import vip.dexian.common.utils.WebUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;


/**
 * 错误页面错误。
 * <p>
 * 注意：请不要把错误页面配置成@GetMapping或者@PostMapping。应该配置成可以接收GET、POST的方式，避免不必要的错误
 *
 * @author 挺好的 2023年05月30日 19:16
 */
@Controller ("adminErrorController")
@RequestMapping ("/error")
@Slf4j
public class ErrorController {

    /**
     * 400
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 400错误
     */
    @RequestMapping (value = "/400")
    public String error400 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.BAD_REQUEST, request, response);
    }

    /**
     * 401
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 401错误
     */
    @RequestMapping (value = "/401")
    public String error401 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.UNAUTHORIZED, request, response);
    }

    /**
     * 403
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 403错误
     */
    @RequestMapping (value = "/403")
    public String error403 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.FORBIDDEN, request, response);
    }

    /**
     * 404
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 404错误
     */
    @RequestMapping (value = "/404")
    public String error404 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.NOT_FOUND, request, response);
    }

    /**
     * 405
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 405错误
     */
    @RequestMapping (value = "/405")
    public String error405 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.METHOD_NOT_ALLOWED, request, response);
    }

    /**
     * 422，该状态码在本系统中的使用场景：
     * <p>
     * 1. 管理员登录的时候
     * <p>
     * 2. 表单校验/业务校验出错的时候
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 422错误
     */
    @RequestMapping (value = "/422")
    public String error422 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.UNPROCESSABLE_ENTITY, request, response);
    }

    /**
     * 500
     *
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 500错误
     */
    @RequestMapping (value = "/500")
    public String error500 (HttpServletRequest request, HttpServletResponse response) {
        return this.error(HttpStatus.INTERNAL_SERVER_ERROR, request, response);
    }

    /**
     * 错误页面处理
     *
     * @param httpStatus
     *         状态码
     * @param request
     *         {@link HttpServletRequest}
     * @param response
     *         {@link HttpServletResponse}
     *
     * @return 如果是ajax请求，则返回json数据，否则返回到具体的错误页面
     */
    private String error (HttpStatus httpStatus, HttpServletRequest request, HttpServletResponse response) {
        Assert.notNull(httpStatus, "http status must be not null");
        response.setStatus(httpStatus.value());

        log.debug(request.getRequestURI());

        if (!WebUtils.isAjaxRequest(request)) {
            return "/admin/error/" + httpStatus.value();
        } else {
            WebUtils.responseMessage(response, Message.error(httpStatus.value()));
        }
        return null;
    }
}
